/**
组合模式（Composite Pattern）

意图：将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
主要解决：它在我们树型结构的问题中，模糊了简单元素和复杂元素的概念，客户程序可以向处理简单元素一样来处理复杂元素，从而使得客户程序与复杂元素的内部结构解耦。
何时使用：
  1、您想表示对象的部分-整体层次结构（树形结构）。
  2、您希望用户忽略组合对象与单个对象的不同，用户将统一地使用组合结构中的所有对象。
如何解决：树枝和叶子实现统一接口，树枝内部组合该接口。
*/
main(List<String> args) {
  Employee ceo = new Employee("John", "CEO", 30000);

  Employee headSales = new Employee("Robert", "Head Sales", 20000);
  Employee headMarketing = new Employee("Michel", "Head Marketing", 20000);

  Employee clerk1 = new Employee("Laura", "Marketing", 10000);
  Employee clerk2 = new Employee("Bob", "Marketing", 10000);

  Employee salesExecutive1 = new Employee("Richard", "Sales", 10000);
  Employee salesExecutive2 = new Employee("Rob", "Sales", 10000);

  ceo.add(headSales);
  ceo.add(headMarketing);

  headSales.add(salesExecutive1);
  headSales.add(salesExecutive2);

  headMarketing.add(clerk1);
  headMarketing.add(clerk2);

  //打印该组织的所有员工
  print(ceo);
  for (Employee headEmployee in ceo.getSubordinates()) {
    print('  $headEmployee');
    for (Employee employee in headEmployee.getSubordinates()) {
      print('    $employee');
    }
  }
}

//////////////////////////////////////////////////////////////////

///
/// 创建 Employee 类，该类带有 Employee 对象的列表
///
class Employee {
  String name;
  String dept;
  int salary;
  List<Employee> subordinates;

  //构造函数
  Employee(this.name, this.dept, this.salary) {
    subordinates = List<Employee>();
  }

  void add(Employee e) {
    subordinates.add(e);
  }

  void remove(Employee e) {
    subordinates.remove(e);
  }

  List<Employee> getSubordinates() {
    return subordinates;
  }

  @override
  String toString() {
    return 'Employee [ name="$name", dept="$dept", salary="$salary" ]';
  }
}
